package com.generation.builder;

import com.generation.Bean.Constants;
import com.generation.Bean.FieldInfo;
import com.generation.Bean.TableInfo;
import com.generation.utils.DateUtils;
import org.apache.commons.lang3.ArrayUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.*;

/**
 * @author mockingjay
 * @date 2023/4/5 - 17:57
 * 生成实体类
 */
public class BuildrPoJo {

    private static final Logger LOGGER = LoggerFactory.getLogger(BuildrPoJo.class);

    public static void excute(TableInfo tableInfo){
        File folder =new File(Constants.PATH_POJO);
        if(!folder.exists()){
            folder.mkdirs();
        }

        File poFile=new File(folder,tableInfo.getBeanName()+".java");

        OutputStream out=null;
        OutputStreamWriter ow=null;
        BufferedWriter bw=null;
        Boolean haveIgnoreBeanField=false;
        StringBuffer buffer=new StringBuffer();
        try {
            out=new FileOutputStream(poFile);
            ow=new OutputStreamWriter(out,"utf8");
            bw=new BufferedWriter(ow);
            bw.write("package "+Constants.PACKAGE_PO+";");
            bw.newLine();
            bw.newLine();
            bw.write("import com.baomidou.mybatisplus.annotation.TableId;");
            bw.newLine();
            bw.write("import com.baomidou.mybatisplus.annotation.TableName;");
            bw.newLine();
            bw.newLine();
            bw.write("import java.io.Serializable;");
            bw.newLine();
            if(tableInfo.getHavaDateTime()||tableInfo.getHaveDate()){
                bw.write("import java.util.Date;");
                bw.newLine();
                bw.write(Constants.BEAN_DATE_FORMAT_CLASS+";");
                bw.newLine();
                bw.write(Constants.BEAN_DATE_UNFORMAT_CLASS+";");
                bw.newLine();
                bw.write("import "+Constants.PACKAGE_UTILS+".DateUtils"+";");
                bw.newLine();
                bw.write("import "+Constants.PACKAGE_ENUM+".DateTimePatternEnum"+";");
                bw.newLine();
            }
            bw.write("import lombok.Data;");
            bw.newLine();
            for(FieldInfo info:tableInfo.getFieldInfoList()){
                if(ArrayUtils.contains(Constants.IGNORE_BEAN_TOJSON_FIELD.split(","),info.getFieldName())){
                    haveIgnoreBeanField=true;
                    bw.write(Constants.IGNORE_BEAN_TOJSON_CLASS+";");
                    bw.newLine();
                    break;
                }
            }
            if(tableInfo.getHaveBigDecimal()){
                bw.write("import java.math.BigDecimal;");
                bw.newLine();
            }
            bw.newLine();
            bw.newLine();
            //构筑类注释
            BuildComment.createClassComment(bw,tableInfo.getComment());
            bw.newLine();
            bw.write("@Data");
            bw.newLine();
            bw.write("@TableName( \""+tableInfo.getTableName()+"\" )");
            bw.newLine();
            bw.write("public class "+tableInfo.getBeanName()+" implements Serializable { ");
            bw.newLine();
            bw.newLine();
            //钩住属性属性
            for(FieldInfo info:tableInfo.getFieldInfoList()){
                BuildComment.createFieldComment(bw,info.getComment());
                bw.newLine();
                //属性有时间
                if(ArrayUtils.contains(Constants.SQL_DATE_TIME_TYPE,info.getSqlType())){
                    bw.write("\t"+String.format(Constants.BEAN_DATE_FORMAT_EXPRESSION, DateUtils.YYYY_MM_DD_HH_MM_SS));
                    bw.newLine();
                    bw.write("\t"+String.format(Constants.BEAN_DATE_UNFORMAT_EXPRESSION, DateUtils.YYYY_MM_DD_HH_MM_SS));
                    bw.newLine();
                }
                //属性有日期
                if(ArrayUtils.contains(Constants.SQL_DATE_TYPE,info.getSqlType())){
                    bw.write("\t"+String.format(Constants.BEAN_DATE_FORMAT_EXPRESSION,DateUtils.YYYY_MM_DD));
                    bw.newLine();
                    bw.write("\t"+String.format(Constants.BEAN_DATE_UNFORMAT_EXPRESSION,DateUtils.YYYY_MM_DD));
                    bw.newLine();
                }
                //是否忽略属性
                if(ArrayUtils.contains(Constants.IGNORE_BEAN_TOJSON_FIELD.split(","),info.getPropertyName())){
                    bw.write("\t"+Constants.IGNORE_BEAN_TOJSON_EXPRESSION);
                    bw.newLine();
                }
                //如果为主键，加入tableId注解
                if(info.getPropertyName().equals(info.getPrimaryKey())){
                    bw.write("\t@TableId");
                    bw.newLine();
                }
                bw.write("\tprivate "+info.getJavaType()+" "+info.getPropertyName()+";");
                bw.newLine();
                bw.newLine();
            }

            bw.write("\t@Override");
            bw.newLine();
            bw.write("\tpublic String toString () {");
            bw.newLine();
            Integer index=0;
            //重写toString
            for (FieldInfo fieldInfo:tableInfo.getFieldInfoList()){
                index++;
                String properName=fieldInfo.getPropertyName();
                if(ArrayUtils.contains(Constants.SQL_DATE_TIME_TYPE,fieldInfo.getSqlType())){
                    properName="DateUtils.format("+ properName + ", DateTimePatternEnum.YYYY_MM_DD_HH_MM_SS.getPattern())";
                }else if(ArrayUtils.contains(Constants.SQL_DATE_TYPE,fieldInfo.getSqlType())){
                    properName="DateUtils.format("+ properName + ", DateTimePatternEnum.YYYY_MM_DD.getPattern())";
                }
                buffer.append(fieldInfo.getComment()+":\" + ("+fieldInfo.getPropertyName()+" == null ? \"空\" : "+properName+")");
                if(index<tableInfo.getFieldInfoList().size()){
                    buffer.append(" + ");
                    buffer.append("\",");
                }

            }
            String tempStr=buffer.toString();
            tempStr="\""+tempStr;
            bw.write("\t\treturn " +tempStr +";");
            bw.newLine();
            bw.write("\t}");
            bw.newLine();
            bw.write("}");
            bw.flush();
        }catch (Exception e){
            LOGGER.error("创建po失败",e);
        }finally {
            if(bw!=null){
                try {
                    bw.close();
                }catch (IOException e){
                    e.printStackTrace();
                }
            }
            if(ow!=null){
                try {
                    ow.close();
                }catch (IOException e){
                    e.printStackTrace();
                }
            }
            if(out!=null){
                try {
                    out.close();
                }catch (IOException e){
                    e.printStackTrace();
                }
            }
        }
    }
}
